package edu.ptu.acl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import edu.ptu.acl.common.MyConstants;
import edu.ptu.acl.dto.DeptTreeDto;
import edu.ptu.acl.dto.param.DeptParam;
import edu.ptu.acl.entity.Dept;
import edu.ptu.acl.entity.User;
import edu.ptu.acl.exception.ApiException;
import edu.ptu.acl.mapper.DeptMapper;
import edu.ptu.acl.mapper.UserMapper;
import edu.ptu.acl.service.IDeptService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.ptu.acl.service.IUserService;
import edu.ptu.acl.utils.SnowIdWorker;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author LinJC
 * @since 2022-03-15
 */
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {

    @Resource
    private DeptMapper deptMapper;
    @Resource
    private UserMapper userMapper;

    @Override
    public List<DeptTreeDto> getDeptTree() {
        List<Dept> allDeptList = deptMapper.selectList(null);

        Multimap<Long,DeptTreeDto> deptTreeMap = ArrayListMultimap.create();

        for (Dept dept : allDeptList) {
            DeptTreeDto deptTreeDto = DeptTreeDto.copyDept(dept);
            deptTreeMap.put(dept.getParentId(),deptTreeDto);
        }

        List<DeptTreeDto> rootDeptTreeDtoList = (List<DeptTreeDto>)deptTreeMap.get(0L);
        Collections.sort(rootDeptTreeDtoList,(d1,d2) -> d1.getSeq()-d2.getSeq());

        recursionDeptTree(rootDeptTreeDtoList,deptTreeMap);

        return rootDeptTreeDtoList;
    }

    public void recursionDeptTree(List<DeptTreeDto> rootDeptTreeDtoList,Multimap<Long,DeptTreeDto> deptTreeMap){
        if (CollectionUtils.isEmpty(rootDeptTreeDtoList)){
            return;
        }
        for (DeptTreeDto deptTreeDto : rootDeptTreeDtoList) {
            List<DeptTreeDto> sonDeptTreeDtoList = (List<DeptTreeDto>)deptTreeMap.get(deptTreeDto.getId());

            Collections.sort(sonDeptTreeDtoList,(d1,d2) -> d1.getSeq()-d2.getSeq() );

            deptTreeDto.setSonDeptTreeList(sonDeptTreeDtoList);
            recursionDeptTree(sonDeptTreeDtoList,deptTreeMap);
        }
    }

    @Override
    public void saveDept(DeptParam deptParam) {
        Dept dept = new Dept();
        BeanUtils.copyProperties(deptParam,dept);

        validateDeptName(dept);

        deptMapper.insert(dept);
    }

    private void validateDeptName(Dept dept) {
        // 同一层级下名字不能一样
        QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.eq("name", dept.getName());
        deptQueryWrapper.eq("parent_id", dept.getParentId());
        deptQueryWrapper.ne("id", dept.getId());
        int count = deptMapper.selectCount(deptQueryWrapper);
        if (count!=0){
            throw new ApiException("同一层级下部门名称不可一致");
        }
    }

    @Override
    public void updateDept(DeptParam deptParam) {
        Dept dept = new Dept();
        BeanUtils.copyProperties(deptParam,dept);
        validateDeptName(dept);
        if (deptMapper.updateById(dept)!=1){
            throw new ApiException(MyConstants.ResultCode.OPTIMISTIC_LOCKING);
        }
    }

    @Override
    public List<String> getCurrentUserDeptName(Long deptId) {
        List<String> deptName = new ArrayList<>();
        recursionGetDeptName(deptId,deptName);
        return deptName;
    }
    public void recursionGetDeptName(Long deptId,List<String> deptName){
        Dept dept = deptMapper.selectById(deptId);
        if (dept == null){
            return;
        }
        deptName.add(dept.getName());
        recursionGetDeptName(dept.getParentId(),deptName);
    }

    @Override
    public void deleteDept(Long id) {
        // 部门底下有用户不给删除
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("dept_id",id);
        if (userMapper.selectCount(queryWrapper)!=0){
            throw new ApiException("该部门底下有员工，不允许删除。");
        }
        QueryWrapper<Dept> deptQueryWrapper = new QueryWrapper<>();
        deptQueryWrapper.eq("parent_id",id);
        if (deptMapper.selectCount(deptQueryWrapper)!=0) {
            throw new ApiException("该部门有子级部门，不允许删除");
        }
        deptMapper.deleteById(id);
    }
}
